package com.sengled.cloud.biz.union.mgt.service.sys.impl;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Update;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.sengled.cloud.biz.union.mgt.common.PageUtil;
import com.sengled.cloud.biz.union.mgt.common.util.Md5Util;
import com.sengled.cloud.biz.union.mgt.dao.sys.CurrentShopDao;
import com.sengled.cloud.biz.union.mgt.dao.sys.ShopAccountDao;
import com.sengled.cloud.biz.union.mgt.dao.sys.ShopDao;
import com.sengled.cloud.biz.union.mgt.dao.sys.UserAccountDao;
import com.sengled.cloud.biz.union.mgt.dao.sys.UserDao;
import com.sengled.cloud.biz.union.mgt.model.po.Shop;
import com.sengled.cloud.biz.union.mgt.model.po.ShopAccount;
import com.sengled.cloud.biz.union.mgt.model.po.User;
import com.sengled.cloud.biz.union.mgt.model.po.UserAccount;
import com.sengled.cloud.biz.union.mgt.model.po.UserAccountDetail;
import com.sengled.cloud.biz.union.mgt.model.po.UserRole;
import com.sengled.cloud.biz.union.mgt.model.po.UserShopAccountPermission;
import com.sengled.cloud.biz.union.mgt.model.request.SaveAccountPwdRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SaveAccountStartStopRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SaveShopRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SaveUserAccountRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SaveUserRequest;
import com.sengled.cloud.biz.union.mgt.model.request.SetAccountStatusRequest;
import com.sengled.cloud.biz.union.mgt.model.request.ShopAccountListRequest;
import com.sengled.cloud.biz.union.mgt.model.request.UserAccountListRequest;
import com.sengled.cloud.biz.union.mgt.model.response.ResponseMessage;
import com.sengled.cloud.biz.union.mgt.model.vo.CurrentModuleShopAccountVo;
import com.sengled.cloud.biz.union.mgt.model.vo.QueryData;
import com.sengled.cloud.biz.union.mgt.model.vo.SelectBoxDataVo;
import com.sengled.cloud.biz.union.mgt.model.vo.ShopDetailVo;
import com.sengled.cloud.biz.union.mgt.model.vo.ShopQueryParamsBean;
import com.sengled.cloud.biz.union.mgt.model.vo.ShopVo;
import com.sengled.cloud.biz.union.mgt.model.vo.UserAccountsVo;
import com.sengled.cloud.biz.union.mgt.model.vo.UserDetailVo;
import com.sengled.cloud.biz.union.mgt.service.sys.IAccountService;
import com.sengled.cloud.biz.union.mgt.service.sys.IShopService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by FMC on 2017/10/27.
 */
@Service("accountService")
@Transactional(value="txManager",rollbackFor = {Exception.class}, propagation = Propagation.REQUIRED)
public class AccountService implements IAccountService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ShopAccountDao shopDao;
    
    @Autowired
    UserAccountDao userAccountDao;
    
    @Autowired
    UserDao userDao;
    
    @Autowired
    CurrentShopDao currentShopDao;
    
    @Override
    public ResponseMessage<List<UserAccountsVo>> listUserAccountsByPage(UserAccountListRequest q) {
    		
    	QueryData<List<UserAccountsVo>> queryData = new QueryData();
    	
        ResponseMessage rm = new ResponseMessage<>();
        if (null == q) {
            rm.buildParamErrorMessage();
            return rm;
        }
        try {
        	boolean isSuperManager = isSuperManager(q.getUserId());
        	q.setSuperMgr(isSuperManager);
        	
            List<UserAccountsVo> ms = userAccountDao.listUsersByPage(q);
            Integer totalRecords = userAccountDao.queryUserTotalRecords(q);
            if (null != ms && !ms.isEmpty()) {
            	
            	for(UserAccountsVo userAccountsVo:ms){
            		List<SelectBoxDataVo> roleList = userAccountDao.getRoleList(userAccountsVo.getId());
            		if(roleList!=null){
            			String roleName="";
            			for(SelectBoxDataVo roleVo:roleList){
            				roleName = roleName+" "+roleVo.getName();
            			}
            			userAccountsVo.setRoleName(roleName);
            		}
            	}
            	queryData.setData(ms);
                
            }
            
            queryData.setTotalCount(totalRecords);
            
            //int totalPages = totalRecords%q.getPageSize()==0?totalRecords/q.getPageSize():totalRecords/totalRecords+1;
            if(totalRecords>0){
				PageUtil pageUtil = new PageUtil(q.getPageNo(),
						q.getPageSize(), totalRecords);
				queryData.setTotalPage(pageUtil.getPageCount());
				queryData.setBeginIndex(pageUtil.getStartIndex());
				queryData.setEndIndex(pageUtil.getEndIndex());
            }else{
            	queryData.setTotalPage(1);
                queryData.setBeginIndex(0);
                queryData.setEndIndex(0);
            }
            queryData.setPageNo(q.getPageNo());
            queryData.setPageSize(q.getPageSize());
            rm.setData(queryData);
            
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    
    
    
    @Override
    public ResponseMessage saveOrUpdateUserAccount(SaveUserAccountRequest saveUserAccountRequest,Long operatorId) {
        ResponseMessage rm = new ResponseMessage<>();
        if (null == saveUserAccountRequest) {
            rm.buildParamErrorMessage();
            return rm;
        }
        
        if(StringUtils.isEmpty(saveUserAccountRequest.getAccountName())||(saveUserAccountRequest.getAccountStatus()==null)||(saveUserAccountRequest.getUserId()==null)||(saveUserAccountRequest.getRoleIds()==null)||(saveUserAccountRequest.getAccountType()==null)){
        	rm.buildParamErrorMessage();
            return rm;
        }
        
        int accountNum = userAccountDao.getAccountCount(saveUserAccountRequest.getAccountName());
       
     
        try {
            
        	UserAccount userAccount = new UserAccount();
            BeanUtils.copyProperties(userAccount, saveUserAccountRequest);
           
            int ret;
            int ret1;
            int ret2;
            if (null != userAccount.getId()) {
               
            	UserAccountDetail userAccountDetail = userAccountDao.selectUserAccount(userAccount.getId());
            	if(userAccountDetail==null){
            		  rm.buildParamErrorMessage();
                      return rm;
            	}
            	
            	if(!userAccountDetail.getAccountName().equals(saveUserAccountRequest.getAccountName())&&accountNum>0){
            		rm.buildAccountRepeatMessage();
                 	return rm;
            	}
                //shop.setCreateDate(new Date());
            	userAccount.setModifyDate(new Date());
            	userAccount.setCompanyId(getCompanyId(operatorId));
            	userAccount.setOperatorId(operatorId);
            	saveUserAccountRequest.setOperatorId(operatorId);
                ret = userAccountDao.updateUserAccount(userAccount);
                //ret1 = userAccountDao.updateAccountRole(userAccount);
                userAccountDao.deleteAccountRole(userAccount.getId());
                ret1 = userAccountDao.insertAccountRole(saveUserAccountRequest);
                userAccountDao.deleteUserShopAccount(userAccount.getId());
                if(null!=saveUserAccountRequest.getShopAccountIds()&&saveUserAccountRequest.getShopAccountIds().size()>0){
                    ret2 = userAccountDao.insertAccountShop(saveUserAccountRequest);                    
                }else{
                	ret2=1;
                }
                
                
                List<Long> currentShopList =  currentShopDao.selectCurrentShopIdByUserKey(userAccount.getId());
                if(currentShopList!=null&&currentShopList.size()>0){
					for (Long shopAccountId : currentShopList) {
						if (saveUserAccountRequest.getShopAccountIds()!=null&&saveUserAccountRequest.getShopAccountIds().size()>0){
							if (!saveUserAccountRequest.getShopAccountIds()
									.contains(shopAccountId)) {
								currentShopDao.deleteByShopAccountId(
										shopAccountId, userAccount.getId());
							}
							
						}else{
							currentShopDao.deleteByShopAccountId(
									shopAccountId, userAccount.getId());
						}
					}
                }
               
            } else {
            	 if(StringUtils.isEmpty(saveUserAccountRequest.getAccountPwd())){
            		 rm.buildParamErrorMessage();
                     return rm;
            	 }
            	 saveUserAccountRequest.setAccountPwd(Md5Util.md5(saveUserAccountRequest.getAccountPwd()));
            	 userAccount.setAccountPwd(saveUserAccountRequest.getAccountPwd());
                 //BeanUtils.copyProperties(userAccount, saveUserAccountRequest);
            	 if(accountNum>0){
                 	rm.buildAccountRepeatMessage();
                 	return rm;
                 }
            	 
            	userAccount.setCreateDate(new Date());
            	//shop.setSealMark(0);
            	userAccount.setCompanyId(getCompanyId(operatorId));
            	userAccount.setOperatorId(operatorId);
            	saveUserAccountRequest.setOperatorId(operatorId);
                ret = userAccountDao.insertUserAccount(userAccount);
                saveUserAccountRequest.setId(userAccount.getId());
                ret1 = userAccountDao.insertAccountRole(saveUserAccountRequest);
                if(null!=saveUserAccountRequest.getShopAccountIds()&&saveUserAccountRequest.getShopAccountIds().size()>0){
                    ret2 = userAccountDao.insertAccountShop(saveUserAccountRequest);
                }else{
                	ret2=1;
                }
            }
            if (0 == ret) {
                rm.buildExecuteFailMessage();
            }
            if (0 == ret1) {
                rm.buildExecuteFailMessage();
            }
            if (0 == ret2) {
                rm.buildExecuteFailMessage();
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            return rm;
        }
    }

    @Override
    public ResponseMessage deleteUserAccount(Long id,Long currentUserId) {
        ResponseMessage rm = new ResponseMessage<>();
        if (null == id || id.intValue() < 0) {
            rm.buildParamErrorMessage();
            return rm;
        }
        try {
        	if(id==currentUserId){
        		rm.buildAccountSelfDeleteMessage();
             	return rm;
        	}
            int ret = userAccountDao.deleteUserAccount(id);
            if (0 == ret) {
                rm.buildExecuteFailMessage();
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            return rm;
        }
    }

    @Override
    public ResponseMessage<UserAccountDetail> getUserAccountDetailById(Long id,Long customerId) {
        ResponseMessage rm = new ResponseMessage<>();
        if (null == id || id.intValue() < 0) {
            rm.buildParamErrorMessage();
            return rm;
        }
        try {
        	
        	UserAccountDetail userAccountDetail = userAccountDao.selectUserAccount(id);
        	
        	if(userAccountDetail==null){
        		 rm.buildParamErrorMessage();
                 return rm;
        	}
        	Long companyId = getCompanyId(customerId);//from login user
        	//List<ShopAccount> shopDetailList = userAccountDao.getShopAccountList(companyId);
        	List<ShopAccount> shopDetailList =  getShopAccountList(customerId);
        	List<Long> selectedShopAccountIds = userAccountDao.getSelectedShopAccountIds(id);
        	List<UserShopAccountPermission> shopPermissionsList = new ArrayList<UserShopAccountPermission>();
        	List<UserShopAccountPermission> shopPermissionsDetailList = new ArrayList<UserShopAccountPermission>();
        	if(shopDetailList!=null){
        		for(ShopAccount shopAccount:shopDetailList){
        			UserShopAccountPermission userShopAccountPermission = new UserShopAccountPermission();
        			userShopAccountPermission.setShopAccountId(shopAccount.getId());
        			userShopAccountPermission.setShopId(shopAccount.getShopId());
        			userShopAccountPermission.setShopCode(shopAccount.getShopCode());
        			userShopAccountPermission.setShopName(shopAccount.getShopName());
        			userShopAccountPermission.setSelected(0);
        			if(selectedShopAccountIds!=null &&selectedShopAccountIds.contains(shopAccount.getId())){
        				userShopAccountPermission.setSelected(1);
        				shopPermissionsDetailList.add(userShopAccountPermission);
        			}
        			shopPermissionsList.add(userShopAccountPermission);
        		}
        	}
        	if(null!=shopPermissionsDetailList&&shopPermissionsDetailList.size()>0){
        	    userAccountDetail.setShopPermissionsSelectedList(shopPermissionsDetailList);
        	}
        	if(null!=shopPermissionsList&&shopPermissionsList.size()>0){        		
        	    userAccountDetail.setShopPermissionsList(shopPermissionsList);
        	}
        	
        	
        	List<SelectBoxDataVo> selectedRoleList = userAccountDao.getRoleList(id);
        	List<Long> roleIds = new ArrayList<Long>();
        	String roles = "";
        	
        	if(selectedRoleList!=null){
        	    for(SelectBoxDataVo data:selectedRoleList){
        		    roles = roles+" "+data.getName();
        		    roleIds.add(data.getId());
        	    }
        	}
        	
        	userAccountDetail.setRoleIds(roleIds);
        	userAccountDetail.setRoleName(roles);
        	
        
            if (null != userAccountDetail) {
                rm.setData(userAccountDetail);
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    
    @Override
    public ResponseMessage<List<SelectBoxDataVo>> getUsers(Long customerId) {
        ResponseMessage rm = new ResponseMessage<>();

        try {
        	
        	//Long companyId = getCompanyId(customerId);
        	List<SelectBoxDataVo> userList = getAllUserList(customerId);//userAccountDao.getAllUserList(companyId);
        
            if (null != userList) {
                rm.setData(userList);
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    @Override
    public ResponseMessage<List<SelectBoxDataVo>> getRoles(Long customerId) {
        ResponseMessage rm = new ResponseMessage<>();

        try {
        	
        	//Long companyId = getCompanyId(customerId);
        	List<SelectBoxDataVo> userList = userAccountDao.getAllRoleList(customerId);
        
            if (null != userList) {
                rm.setData(userList);
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            return rm;
        }
    }

    
    @Override
    public ResponseMessage<List<ShopAccount>> getShopPermissions(Long customerId) {
        ResponseMessage rm = new ResponseMessage<>();

        try {	
        	List<ShopAccount> shopPermissionList =  getShopAccountList(customerId);
        	
            if (null != shopPermissionList) {
                rm.setData(shopPermissionList);
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    
    public List<ShopAccount> getShopAccountList(Long customerId){
    	Long companyId = getCompanyId(customerId);
    	
    	boolean isSuperManager = isSuperManager(customerId);
    	List<ShopAccount> shopPermissionList = new ArrayList<ShopAccount>();
    	
    	if(isSuperManager){
    		shopPermissionList = userAccountDao.getShopAccountList(companyId);
    	}else{
    		shopPermissionList = userAccountDao.getCurrentShopAccountList(companyId, customerId);
    	}
    	return shopPermissionList;
    }
    
    public List<SelectBoxDataVo> getAllUserList(Long customerId){
    	Long companyId = getCompanyId(customerId);
    	
    	boolean isSuperManager = isSuperManager(customerId);
    	
    	List<SelectBoxDataVo> userList = new ArrayList<SelectBoxDataVo>();
    	
    	if(isSuperManager){
    		userList = userAccountDao.getAllUserList(companyId);
    	}else{
    		userList =userAccountDao.getCurrentUserList(companyId, customerId);
    	}
    	return userList;
    }
    
  
    @Override
    public ResponseMessage updateUserAccountPwd(SaveAccountPwdRequest saveAccountPwdRequest) {
        ResponseMessage rm = new ResponseMessage<>();
        if (null == saveAccountPwdRequest) {
            rm.buildParamErrorMessage();
            return rm;
        }
        if(saveAccountPwdRequest.getId()==null||StringUtils.isEmpty(saveAccountPwdRequest.getPwd())){
        	rm.buildParamErrorMessage();
            return rm;
        }
        saveAccountPwdRequest.setPwd(Md5Util.md5(saveAccountPwdRequest.getPwd()));
        try {
            int ret = userAccountDao.updateUserAccountPwd(saveAccountPwdRequest);
            if (0 == ret) {
                rm.buildExecuteFailMessage();
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    
    @Override
    public ResponseMessage updateAccountStartStop(SaveAccountStartStopRequest saveAccountStartStopRequest) {
        ResponseMessage rm = new ResponseMessage<>();
        if (null == saveAccountStartStopRequest) {
            rm.buildParamErrorMessage();
            return rm;
        }
        if(saveAccountStartStopRequest.getId()==null||saveAccountStartStopRequest.getEnableMark()==null){
        	rm.buildParamErrorMessage();
            return rm;
        }
        try {
            int ret = userAccountDao.updateAccountStartStop(saveAccountStartStopRequest);
            if (0 == ret) {
                rm.buildExecuteFailMessage();
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            rm.buildSystemErrorMessage();
            return rm;
        }
    }
    
    @Override
    public Long getCompanyId(Long userId){
    	//Long userId = 1L;
    	Long companyId = userDao.queryUserCompanyId(userId);
    	return companyId;

    }
    
    
    @Override
    public String getUserAccountNameById(Long id) {
      
        if (null == id || id.intValue() < 0) {
            return null;
        }
        try {
        	
        	UserAccountDetail userAccountDetail = userAccountDao.selectUserAccount(id);
        	
        	if(userAccountDetail==null){
        		return null;
        	}
        	return userAccountDetail.getAccountName();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }
    
    @Override
    public boolean setAccountStatusById(SetAccountStatusRequest setAccountStatusRequest) {
        
        try {
            int ret = userAccountDao.setAccountStatusById(setAccountStatusRequest);
            if (0 == ret) {
               return false;
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    
    @Override
    public boolean setAccountStatusByName(SetAccountStatusRequest setAccountStatusRequest) {
        
        try {
            int ret = userAccountDao.setAccountStatusByName(setAccountStatusRequest);
            if (0 == ret) {
               return false;
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
    
    @Override
    public ResponseMessage<Long> getUserRoleId(Long userId){
    	
    	
    	ResponseMessage rm = new ResponseMessage<>();

        try {
        	
        	//Long userId = 1L;
        	Long roleId = userDao.getUserRoleIdByUserId(userId);
      
        
            if (null != roleId) {
                rm.setData(roleId);
            }else{
            	rm.setData(-1L);
            }
            return rm;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            rm.buildSystemErrorMessage();
            rm.setData(-1L);
            return rm;
        }
    }
    
 public boolean isSuperManager(Long customerId) {
        
        try {
            int ret = userAccountDao.getSuperManager(customerId);
            if (0 == ret) {
               return false;
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }
}
